package com.nakamachizu.controller;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
import org.slim3.controller.validator.Validators;
import org.slim3.datastore.Datastore;
import org.slim3.util.StringUtil;
import org.slim3.util.TimeZoneLocator;

import com.google.appengine.api.datastore.GeoPt;
import com.nakamachizu.constant.AppConstant;
import com.nakamachizu.constant.MixiConstant;
import com.nakamachizu.constant.SessionKeyConstant;
import com.nakamachizu.model.MapData;
import com.nakamachizu.model.MemberData;
import com.nakamachizu.model.session.MapDataSession;
import com.nakamachizu.service.MapDataService;
import com.nakamachizu.util.ErrorsUtil;
import com.nakamachizu.util.ForwardUtil;

public class AddMemberController extends Controller {

    private String keyStr;
    private String name;
    private String password;
    private String comment;
    private String lat;
    private String lng;
    
    private Calendar now;
    private String ipAddress;
    
    protected List<String> messages = new ArrayList<String>();
    
    @Override
    public Navigation run() throws Exception {
        
        init();
        
        if(StringUtil.isEmpty(keyStr)){
            return redirect("/make");
        }

        MapDataService service = new MapDataService();
        MapData map = service.getMapDataAccessKey(keyStr);
        
        
        if(map != null && validate()){
            requestScope("key", keyStr);
            requestScope("serverName", request.getServerName());
            
            if(!StringUtil.isEmpty(map.getViewPassword())){
                MapDataSession mds = sessionScope(SessionKeyConstant.MAP_DATA_SESSION_KEY());
                if(mds == null || !map.getViewPassword().equals(mds.getViewPassword())){
                    messages.add("パスワードが違います。");
                    requestScope("messages", messages);
                    return forward(ForwardUtil.forwardJsp("input_password.jsp"));
                }
            }
            
            List<MemberData>list = map.getMemberDataListRef().getModelList();
            if(list != null && list.size() >= AppConstant.MAX_MEMBER_NUM()){
                ErrorsUtil.putErrors(errors, request, "message.error.maxmember", "max_member");
                return forward("/map?key=" + keyStr);
            }
            MemberData mem = this.getMember(name, list);
            if(mem == null){
                mem = new MemberData();
                mem.setEntryDate(now.getTime());
                if(map.getAdminMailAddress().matches("^[0-9]+" + MixiConstant.MIXI_MAIL_ADDRESS() + "$")){
                    Calendar exp = Calendar.getInstance(TimeZoneLocator.get());
                    exp.add(Calendar.MINUTE, MixiConstant.MIXI_GPS_EXPIRE_MINUTES());
                    mem.setExpireDate(exp.getTime());
                }

            }else{
                if(!password.equals(mem.getEditPassword())){
                    messages.add("地図上に同じ名前の参加者が存在します。同じ名前の場合はパスワードが一致しないと更新できません。");
                    requestScope("messages", messages);
                    return forward(ForwardUtil.forwardJsp("map.jsp"));
                }
            }
            GeoPt pt = new GeoPt(Float.parseFloat(lat), Float.parseFloat(lng));
            mem.setName(name);
            mem.setComment(comment);
            mem.setEditPassword(password);
            mem.setIpAddress(ipAddress);
            mem.setLatLng(pt);
            mem.setPcIconName(service.createMemberPcIconName(list));
            mem.setMIconName(service.createMobileMemberIconName(list));
            mem.setModifyDate(now.getTime());
            mem.getMapDataRef().setModel(map);
            //mem.setMarkType(AppConstant.MARK_TYPE_NAKAMACHIZU());
            Calendar expire = Calendar.getInstance(TimeZoneLocator.get());
            expire.set(2050, 12, 31);
            mem.setExpireDate(expire.getTime());
            
            Datastore.put(mem);
        }

        return redirect("/map?key=" + keyStr);
    }
    
    private void init(){
        keyStr = requestScope("key");
        name = requestScope("name");
        password = requestScope("password");
        comment = requestScope("comment");
        lat = requestScope("lat");
        lng = requestScope("lng");
        
        now = Calendar.getInstance(TimeZoneLocator.get());
        ipAddress = request.getRemoteAddr();
    }
    
    protected boolean validate() {
        boolean result = false;
        Validators v = new Validators(request);
        String reqKey = requestScope("key");
        if(StringUtil.isEmpty(reqKey)){
            MapDataSession ses = sessionScope(SessionKeyConstant.MAP_DATA_SESSION_KEY());
            if(ses != null){
                requestScope("key", ses.getMapKey());
            }
        }
        v.add("key", v.required());
        v.add("name", v.required());
        v.add("password", v.required());
        v.add("comment", v.required());
        v.add("lat", v.required());
        v.add("lat", v.doubleType());
        v.add("lng", v.required());
        v.add("lng", v.doubleType());
        
        result = v.validate();
        
        return result;
    }
    
    protected MemberData getMember(String name, List<MemberData>list){
        if(list != null && list.size() > 0){
            for(MemberData mem : list){
                if(mem.getName().equals(name)){
                    return mem;
                }
            }
        }
        
        return null;
    }
}
